#main

public fn0(str) {
	echo str
}

var a_function = fn0
var a_string = "string"
a_function('call with callable type')  	// okay
// a_string('call with string type')  		// error

internal fn1(callee Callable) {
	var unknow_type_value Any = callee('hei')
}

fn1(fn0)
fn1((str) => fn0(str))

// parameter reference
internal fn2(&n Int) {
	n += 1
}

internal Data {
	ABC = 11
	static num = 3000
}

var num = 1000
var arr = [2000]

fn2(num)  		// okay
fn2(arr[0])		// okay
fn2(Data.num)   // okay
// fn2(1000)    // error
// fn2(Data.ABC) // error
echo 'num referenced by fn2: $num'
echo 'arr[0] referenced by fn2: ${arr[0]}'
echo 'Data.num referenced by fn2: ${Data.num}'

// callbacks
internal fn3(some Any, done (caller String) String, error (message) = none) String {
	return done('A cool man') concat ' with $some'
}

echo fn3(123, done: (a) => {
		return a concat ' has called'
	}, error: (error) => {})

echo fn3('any...') -> done(caller String) {
	return "$caller has called!"
}
